#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
配置管理器

统一管理项目的所有配置，提供配置的加载、保存、更新等功能。
整合原有的config.py和config.json功能。

作者: AI Assistant
创建时间: 2024
"""

import json
import os
from typing import Dict, List, Any, Optional
from datetime import datetime
from pathlib import Path

from .base_config import BaseConfig
from .development import DevelopmentConfig
from .production import ProductionConfig
from .logger_config import get_logger, setup_logger_from_config


class ConfigManager:
    """配置管理器"""
    
    def __init__(self, config: BaseConfig = None, config_file: str = None):
        """
        初始化配置管理器
        
        Args:
            config (BaseConfig, optional): 配置对象
            config_file (str, optional): 配置文件路径
        """
        self.logger = get_logger(__name__)
        
        # 确定配置文件路径
        # 新配置系统不再使用config.json文件
        self.config_file = config_file
        
        # 初始化配置
        if config:
            self.config = config
        else:
            # 根据环境变量确定配置类型
            env = os.getenv('FLASK_ENV', 'development')
            self.config = self._create_config_by_env(env)
        
        # 设置日志配置
        setup_logger_from_config(self.config.logger)
        
        # 加载配置文件（如果存在）
        self._load_config_file()
        
        self.logger.info(f"配置管理器初始化完成，环境: {self.config.flask.environment}")
    
    def _create_config_by_env(self, env: str) -> BaseConfig:
        """根据环境创建配置对象"""
        config_map = {
            'development': DevelopmentConfig,
            'production': ProductionConfig
        }
        
        config_class = config_map.get(env, DevelopmentConfig)
        return config_class()
    
    def _load_config_file(self):
        """从配置文件加载配置"""
        if self.config_file and os.path.exists(self.config_file):
            try:
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    config_data = json.load(f)
                
                # 更新微信配置
                if 'wechat' in config_data:
                    self._update_wechat_config(config_data['wechat'])
                
                # 更新新闻配置
                if 'news' in config_data:
                    self._update_news_config(config_data['news'])
                
                # 更新其他配置
                if 'reply' in config_data:
                    # 兼容旧的reply配置
                    self._update_reply_config(config_data['reply'])
                
                self.logger.info(f"从配置文件加载配置: {self.config_file}")
                
            except Exception as e:
                self.logger.error(f"加载配置文件失败: {e}")
        else:
            # 创建默认配置文件
            self._create_default_config_file()
    
    def _update_wechat_config(self, wechat_data: Dict[str, Any]):
        """更新微信配置"""
        for key, value in wechat_data.items():
            if hasattr(self.config.wechat, key):
                setattr(self.config.wechat, key, value)
    
    def _update_news_config(self, news_data: Dict[str, Any]):
        """更新新闻配置"""
        for key, value in news_data.items():
            if hasattr(self.config.news, key):
                setattr(self.config.news, key, value)
    
    def _update_reply_config(self, reply_data: Dict[str, Any]):
        """更新回复配置（兼容旧格式）"""
        # 映射旧的reply配置到新的wechat配置
        mapping = {
            'enabled': 'auto_reply_enabled',
            'default_reply': 'default_reply_message',
            'welcome_message_template': 'welcome_template',
            'reply_to_private': 'reply_to_private',
            'reply_to_group_at_only': 'reply_to_group_at_only'
        }
        
        for old_key, new_key in mapping.items():
            if old_key in reply_data and hasattr(self.config.wechat, new_key):
                setattr(self.config.wechat, new_key, reply_data[old_key])
    
    def _create_default_config_file(self):
        """创建默认配置文件"""
        if not self.config_file:
            # 新配置系统不使用配置文件
            return
            
        try:
            # 确保目录存在
            Path(self.config_file).parent.mkdir(parents=True, exist_ok=True)
            
            # 保存当前配置
            self.save_config()
            self.logger.info(f"创建默认配置文件: {self.config_file}")
            
        except Exception as e:
            self.logger.error(f"创建默认配置文件失败: {e}")
    
    def save_config(self):
        """保存配置到文件"""
        try:
            # 确保目录存在
            Path(self.config_file).parent.mkdir(parents=True, exist_ok=True)
            
            config_data = {
                'wechat': self.config.wechat.__dict__,
                'news': self.config.news.__dict__,
                'database': {
                    'type': self.config.database.type,
                    'database': self.config.database.database,
                    # 不保存敏感信息到文件
                },
                'flask': {
                    'environment': self.config.flask.environment,
                    'debug': self.config.flask.debug,
                    'host': self.config.flask.host,
                    'port': self.config.flask.port
                },
                'logger': {
                    'level': self.config.logger.level,
                    'file_path': self.config.logger.file_path,
                    'console_output': self.config.logger.console_output
                },
                'paths': self.config.paths.__dict__,
                'last_updated': datetime.now().isoformat(),
                'environment': self.config.flask.environment
            }
            
            with open(self.config_file, 'w', encoding='utf-8') as f:
                json.dump(config_data, f, ensure_ascii=False, indent=2)
            
            self.logger.info(f"配置已保存到: {self.config_file}")
            
        except Exception as e:
            self.logger.error(f"保存配置文件失败: {e}")
    
    def update_wechat_config(self, **kwargs):
        """更新微信配置"""
        for key, value in kwargs.items():
            if hasattr(self.config.wechat, key):
                setattr(self.config.wechat, key, value)
                self.logger.info(f"更新微信配置: {key} = {value}")
        
        self.save_config()
    
    def update_news_config(self, **kwargs):
        """更新新闻配置"""
        for key, value in kwargs.items():
            if hasattr(self.config.news, key):
                setattr(self.config.news, key, value)
                self.logger.info(f"更新新闻配置: {key} = {value}")
        
        self.save_config()
    
    def update_database_config(self, **kwargs):
        """更新数据库配置"""
        for key, value in kwargs.items():
            if hasattr(self.config.database, key):
                setattr(self.config.database, key, value)
                self.logger.info(f"更新数据库配置: {key} = {value}")
        
        self.save_config()
    
    def update_logger_config(self, **kwargs):
        """更新日志配置"""
        for key, value in kwargs.items():
            if hasattr(self.config.logger, key):
                setattr(self.config.logger, key, value)
                self.logger.info(f"更新日志配置: {key} = {value}")
        
        # 重新设置日志配置
        setup_logger_from_config(self.config.logger)
        self.save_config()
    
    def add_news_group(self, group_name: str):
        """添加新闻推送群"""
        if group_name not in self.config.news.target_groups:
            self.config.news.target_groups.append(group_name)
            self.logger.info(f"添加新闻推送群: {group_name}")
            self.save_config()
    
    def remove_news_group(self, group_name: str):
        """移除新闻推送群"""
        if group_name in self.config.news.target_groups:
            self.config.news.target_groups.remove(group_name)
            self.logger.info(f"移除新闻推送群: {group_name}")
            self.save_config()
    
    def get_all_config(self) -> Dict[str, Any]:
        """获取所有配置"""
        return self.config.to_dict()
    
    def get_wechat_config(self) -> Dict[str, Any]:
        """获取微信配置"""
        return self.config.wechat.__dict__
    
    def get_news_config(self) -> Dict[str, Any]:
        """获取新闻配置"""
        return self.config.news.__dict__
    
    def get_database_config(self) -> Dict[str, Any]:
        """获取数据库配置"""
        return self.config.database.__dict__
    
    def get_flask_config(self) -> Dict[str, Any]:
        """获取Flask配置"""
        return self.config.get_flask_config()
    
    def get_database_url(self) -> str:
        """获取数据库连接URL"""
        return self.config.get_database_url()
    
    def reload_config(self):
        """重新加载配置"""
        self.logger.info("重新加载配置")
        self._load_config_file()
        setup_logger_from_config(self.config.logger)
    
    def validate_config(self) -> List[str]:
        """验证配置"""
        errors = []
        
        # 验证数据库配置
        if self.config.database.type == 'postgresql' and not self.config.database.password:
            errors.append("PostgreSQL数据库需要设置密码")
        
        # 验证Flask配置
        if self.config.flask.environment == 'production' and self.config.flask.secret_key == 'dev-secret-key-change-in-production':
            errors.append("生产环境需要设置安全的SECRET_KEY")
        
        # 验证路径配置
        for path_name in ['backup_dir', 'temp_dir', 'log_dir']:
            path = getattr(self.config.paths, path_name)
            if not os.path.exists(path):
                try:
                    Path(path).mkdir(parents=True, exist_ok=True)
                except Exception:
                    errors.append(f"无法创建目录: {path}")
        
        return errors
    
    def export_config(self, file_path: str, include_sensitive: bool = False):
        """导出配置到文件"""
        try:
            config_data = self.config.to_dict()
            
            if not include_sensitive:
                # 移除敏感信息
                if 'database' in config_data and 'password' in config_data['database']:
                    config_data['database']['password'] = '***'
                if 'flask' in config_data and 'secret_key' in config_data['flask']:
                    config_data['flask']['secret_key'] = '***'
            
            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(config_data, f, ensure_ascii=False, indent=2)
            
            self.logger.info(f"配置已导出到: {file_path}")
            
        except Exception as e:
            self.logger.error(f"导出配置失败: {e}")
            raise
    
    def get_env_var(self, key: str, default: Any = None) -> Any:
        """获取环境变量"""
        return os.getenv(key, default)
    
    def set_env_var(self, key: str, value: str):
        """设置环境变量"""
        os.environ[key] = value
        self.logger.info(f"设置环境变量: {key} = {value}")
    
    def import_config(self, file_path: str):
        """从文件导入配置"""
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                config_data = json.load(f)
            
            # 更新配置
            if 'wechat' in config_data:
                self._update_wechat_config(config_data['wechat'])
            
            if 'news' in config_data:
                self._update_news_config(config_data['news'])
            
            self.save_config()
            self.logger.info(f"从文件导入配置: {file_path}")
            
        except Exception as e:
            self.logger.error(f"导入配置失败: {e}")
            raise